import { Injectable } from '@nestjs/common';
import { CreateProjectDto } from './dto/create-project.dto';
import { UpdateProjectDto } from './dto/update-project.dto';
import { ResultData } from 'src/common/utils/result';
import { PrismaService } from '@/module/common/prisma/prisma.service';
import { pickEquals, pickLike } from '@/common/utils/prisma';
import { PrismaConst } from '@/common/constant/prisma.constant';
import { ListProjectDto } from './dto/list-project.dto';
import { User } from '@/module/common/prisma/client';
import { ListAnnexDto } from './dto/list-annex.dto';
@Injectable()
export class ProjectService {
    constructor(
        private readonly prisma: PrismaService
    ) { }
    async create(user: User, createProjectDto: CreateProjectDto) {

        const newProject = await this.prisma.project.create({ data: { ...pickEquals(createProjectDto, PrismaConst.project), createBy: user.userName } });
        const leader = createProjectDto.leader.map(item => ({
            projectId: newProject.projectId,
            userId: item,
            isLeader: true
        }))
        const member = createProjectDto.member.map(item => ({
            projectId: newProject.projectId,
            userId: item,
            isLeader: false
        }))
        await this.prisma.projectUser.createMany({
            data: [...leader, ...member]
        })
        return ResultData.ok();
    }

    async findAll(query: ListProjectDto) {

        let where: any = {
            delFlag: '0',
            ...pickEquals(query, ['status']),
            ...pickLike(query, ['projectName']),
        }
        const and = []
        if (query.leader) {
            query.leader.forEach(item => {
                and.push({
                    users: {
                        some: {
                            userId: item,
                            isLeader: true,
                        },
                    },
                })
            })
        }
        if (query.member) {
            query.member.forEach(item => {
                and.push({
                    users: {
                        some: {
                            userId: item,
                            isLeader: false,
                        },
                    },
                })
            })
        }
        where.AND = and
        let skip = void 0
        let take = void 0
        if (query.pageSize && query.pageNum) {
            skip = (query.pageNum - 1) * query.pageSize
            take = +query.pageSize
        }
        if (query?.beginTime && query?.endTime) {
            where.beginTime = {
                gte: new Date(query.beginTime),
                lte: new Date(query.endTime),
            }
        }
        const [list, total] = await Promise.all([
            this.prisma.project.findMany({
                where,
                skip,
                take,
                orderBy: {
                    createTime: 'desc',
                },
                include: {
                    users: {
                        include: {
                            user: {
                                select: {
                                    userId: true,
                                    nickName: true,
                                }
                            }, // 嵌套查询 User 表，获取用户详细信息
                        },
                    }
                },
            }),
            this.prisma.project.count({ where }),
        ]);
        list.forEach(project => {
            //@ts-ignore
            project.leader = project.users.filter(item => item.isLeader).map(item => item.user)
            //@ts-ignore
            project.member = project.users.filter(item => !item.isLeader).map(item => item.user)
        });
        return ResultData.ok({
            list,
            total,
        });
    }

    async findFirst(projectName: string) {
        const project = await this.prisma.project.findFirst({ where: { projectName, delFlag: '0' } })

        return ResultData.ok({ isRepeat: !!project });
    }

    async update(user: User, updateProjectDto: UpdateProjectDto) {

        await this.prisma.project.update({
            where: {
                projectId: updateProjectDto.projectId,
            },
            data: {
                ...pickEquals(updateProjectDto, PrismaConst.project.filter(item => item !== 'projectId')),
                updateBy: user.userName,
            },
        });
        await this.prisma.projectUser.deleteMany({
            where: {
                projectId: updateProjectDto.projectId,
            },
        });
        const leader = updateProjectDto.leader.map(item => ({
            projectId: updateProjectDto.projectId,
            userId: item,
            isLeader: true
        }))
        const member = updateProjectDto.member.map(item => ({
            projectId: updateProjectDto.projectId,
            userId: item,
            isLeader: false
        }))
        await this.prisma.projectUser.createMany({
            data: [...leader, ...member]
        })
        return ResultData.ok();
    }

    async updateStatus(user: User, updateStatusDto: { projectId: number, status: string }) {
        const data: any = {
            status: String(updateStatusDto.status)
        }
        const project = await this.prisma.project.findUnique({
            where: {
                projectId: updateStatusDto.projectId,
            },
            select: {
                status: true,
            }
        })
        console.log(project, 'project', updateStatusDto);

        if (project.status === '0' && String(updateStatusDto.status) === '1') {
            data.beginTime = new Date()
        }
        if (project.status === '3' && String(updateStatusDto.status) === '4') {
            data.endTime = new Date()
        }
        await this.prisma.project.update({
            where: {
                projectId: updateStatusDto.projectId,
            },
            data
        })
        return ResultData.ok();
    }

    async remove(ids: number[]) {
        await this.prisma.project.updateMany({
            where: {
                projectId: { in: ids },
            },
            data: {
                delFlag: '1',
            },
        });
        return ResultData.ok();
    }

    async createAnnex(id: number, uploadId: string, type: string) {
        return await this.prisma.projectAnnex.create({
            data: {
                projectId: id,
                uploadId,
                type
            }
        })
    }

    async findAllAnnex(id: number, query: ListAnnexDto) {

        const uploadIds = await this.prisma.projectAnnex.findMany({
            where: {
                projectId: id,
                ...pickLike(query, ['type'])
            },
            select: {
                uploadId: true
            }
        })
        const uploads = await this.prisma.upload.findMany({
            where: {
                uploadId: { in: uploadIds.map(item => item.uploadId) },
                ...pickLike(query, ['originalName']),
                ...pickEquals(query, ['status', 'createBy'])
            },
            include: {
                user: {
                    select: {
                        userId: true,
                        nickName: true,
                    }
                },
                project: {
                    select: {
                        type: true,
                    }
                }
            }
        })
        uploads.forEach(item => {
            //@ts-ignore
            item.type = item.project[0].type
            delete item.project
        })
        return ResultData.ok(uploads);

    }

    async removeAnnex(ids: string[]) {
        await this.prisma.projectAnnex.deleteMany({
            where: {
                uploadId: {
                    in: ids,
                },
            }
        });
        await this.prisma.upload.updateMany({
            where: {
                uploadId: {
                    in: ids,
                },
            },
            data: {
                delFlag: '1',
            }
        });
        return ResultData.ok();
    }

    async findMemberAndScore() {
        const users = await this.prisma.projectUser.findMany({
            
        })
    }
}
